<template>
  <div class="data-collection">
    <!-- 上部分：状态栏 -->
    <div class="status-bar">
      <div class="status-left">
        <span class="time">当前时间：{{ currentTime }}</span>
        <el-divider direction="vertical" />
        <span class="status">
          <el-tag
              :type="collectionStatus === '采集中' ? 'success' : 'info'"
              size="small"
          >
            {{ collectionStatus }}
          </el-tag>
        </span>
        <el-divider direction="vertical" />
        <span class="countdown">{{ collectionDuration }}</span>
        <el-button
            type="danger"
            size="small"
            @click="stopCollection"
            :disabled="collectionStatus === '待机'"
        >
          停止
        </el-button>
      </div>
      <div class="status-right">
        <el-button
            type="primary"
            @click="toggleCollection"
            :disabled="collectionStatus === '采集中'"
        >
          开始采集
        </el-button>
      </div>
    </div>

    <!-- 工具栏：添加状态检测按钮 -->
    <div class="video-toolbar">
      <div class="toolbar-left">
        <el-button
            size="small"
            type="primary"
            @click="loadVideoStreamList"
            :loading="isLoadingVideoList"
            :disabled="collectionStatus === '采集中'"
        >
          <el-icon><Refresh /></el-icon>
          {{ isLoadingVideoList ? '加载中...' : '刷新视频流' }}
        </el-button>

        <span style="margin-left: 10px; color: #666; font-size: 12px;">
          总数: {{ videoList.length }} |
          已启用: {{ videoList.filter(v => v.isEnabled).length }} |
          已停用: {{ videoList.filter(v => !v.isEnabled).length }} |
          在线: {{ videoList.filter(v => v.isEnabled && v.status === 'online').length }} |
          离线: {{ videoList.filter(v => v.isEnabled && v.status === 'offline').length }}
        </span>
      </div>
      <div class="toolbar-right">
        <span class="toolbar-label">窗口布局</span>
        <el-select
            v-model="windowLayout"
            size="small"
            style="width: 120px"
            @change="refreshGrid"
        >
          <el-option label="每行2路" value="2" />
          <el-option label="每行3路" value="3" />
          <el-option label="每行4路" value="4" />
        </el-select>
      </div>
    </div>

    <!-- 视频卡片区：高度固定，超出滚动 -->
    <div class="video-scroll-wrapper scroll-wrapper">
      <!-- 空状态显示 -->
      <div v-if="videoList.length === 0 && !isLoadingVideoList" class="empty-state">
        <el-empty description="暂无视频流数据">
          <el-button type="primary" @click="loadVideoStreamList">
            刷新视频流
          </el-button>
        </el-empty>
      </div>

      <!-- 加载状态显示 -->
      <div v-else-if="isLoadingVideoList" class="loading-state">
        <p> ...</p>
      </div>

      <!-- 视频网格 -->
      <div v-else class="video-grid" :style="gridStyle">
        <div
            v-for="(item, i) in filteredVideoList"
            :key="item.id"
            class="video-card"
            :class="{ 'disabled': !item.isEnabled }"
        >
          <!-- 左上角title和状态 -->
          <div class="video-card-topbar">
            <span class="video-title">{{ item.name || item.title }}</span>
            <span
                class="video-status-text"
                :class="getStatusDisplay(item).class"
                :title="item.errorMessage || `最后检测: ${item.lastCheck ? new Date(item.lastCheck).toLocaleTimeString() : '未检测'}`"
            >
              {{ getStatusDisplay(item).text }}
            </span>
          </div>
          <!-- 右上角icon -->
          <div class="video-card-icons">
            <el-tooltip
                :content="item.collecting ? '取消采集' : '加入采集'"
                placement="top"
            >
              <el-icon
                  class="video-icon"
                  @click.stop="toggleCollect(i)"
                  :class="{
                  disabled: collectionStatus === '采集中' || !item.isEnabled || item.status === 'offline',
                  collecting: item.collecting
                }"
              >
                <component :is="item.collecting ? UnlinkIcon : 'Link'" />
              </el-icon>
            </el-tooltip>

            <el-tooltip :content="getFullscreenTooltip(i)" placement="top">
              <el-icon
                  class="video-icon"
                  @click.stop="maximizeVideo(i)"
                  :class="{
                  disabled: !item.isEnabled || item.status === 'offline',
                  fullscreen: isVideoFullscreen(i)
                }"
              >
                <ZoomOut v-if="isVideoFullscreen(i)" />
                <FullScreen v-else />
              </el-icon>
            </el-tooltip>

          </div>
          <div class="video-card-body">
            <RtspVideoPlayer
                v-if="item.isEnabled"
                :ref="(el) => (videoRefs.set(item.id, el))"
                :rtsp-url="item.src"
                :hide-controls="true"
                :show-controls="false"
                :autoplay="true"
                @error="handleVideoError"
                @connected="handleVideoConnected"
                @reconnectFailed="handleVideoReconnectFailed"
                @fullscreenChange="(isFullscreen) => handleFullscreenChange(isFullscreen, item.id)"
            />
            <div v-else class="video-placeholder disabled">
              <div class="disabled-content">
                <h4 class="disabled-title">已停用</h4>
                <p class="disabled-message">该视频流已被后台停用</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="data-container" v-show="selectIs">
      <!-- 操作栏 -->
      <div class="data-controls">
        <h2 class="section-title">任务选择<span style="font-size: 14px">（用于筛选显示的遥测数据）</span></h2>        
      </div>

      <!-- 数据展示网格 - 一行四个 -->
      <!-- 当前已确认的选择 -->
      <div v-if="confirmedSelection" class="selected-task-info">
        <div class="info-header">
          <h3>当前选择</h3>
          <el-button type="primary" size="small" @click="reselectTask">重新选择</el-button>
        </div>
        <div class="info-content">
          <p><strong>任务:</strong> {{ confirmedSelection.taskId }}-{{ confirmedSelection.taskName }}</p>
          <div><strong>参数:</strong> <el-tag v-for="name in confirmedSelection.paramNames" :key="name" size="small" style="margin-left: 8px;">{{ name }}</el-tag></div>
        </div>
      </div>
      
      <!-- 任务选择区域 -->
      <div class="data-grid task-content scroll-wrapper">
        <div
            v-for="item in taskList"
            :key="item.id"
            class="data-card"
            :class="{ 'selected': isItemSelected(item.id) }"
            @click="toggleSelection(item.id, $event)"
        >
          <!-- 单选框 -->
          <div class="card-checkbox">
            <input
                type="radio"
                name="taskRadio"
                :id="`data-${item.id}`"
                :checked="isItemSelected(item.id)"
                @change="(e) => toggleSelection(item.id, e)"
            >
            <label :for="`data-${item.id}`" class="custom-checkbox"></label>
          </div>

          <!-- 数据内容 -->
          <div class="card-content">
            <h3 class="data-name">{{ item.id }}-{{ item.name }}</h3>
          </div>
        </div>
      </div>
    </div>
    <!-- 下部分：遥测数据图表 -->
    <div class="chart-section" v-show="!selectIs">
      <TelemetryChart
          ref="telemetryChartRef"
          :historicalData="telemetryChartDataList"
          :is-collecting="collectionStatus === '采集中'"
          :window-layout="windowLayout"
          :task-name="confirmedSelection?.taskName || '未选择任务'"
      />
    </div>

    <!-- 采集完成确认弹窗 -->
    <el-dialog v-model="showConfirmDialog" title="采集完成确认" width="400px">
      <p>数据采集已完成，是否完成本次采集？</p>
      <div style="margin: 15px 0; padding: 10px; background: #f5f5f5; border-radius: 4px;">
        <p style="margin: 0; font-size: 14px; color: #666;">
        采集时长: {{ formatTime(actualCollectionDuration) }}<br>
        采集路数: {{ videoList.filter(v => v.isEnabled && v.status === 'online').length }} 路<br>
        采集遥测参数: {{ paramConfigsList.length || 0 }} 个<br>
        采集ID: {{ collectionId }}
      </p>
      </div>
      <template #footer>
        <el-button @click="cancelSave">取消</el-button>
        <el-button type="primary" @click="confirmSave">确认完成</el-button>
      </template>
    </el-dialog>
    
    <!-- 参数选择对话框 -->
    <el-dialog v-model="showParamDialog" :title="`选择${currentTaskName}参数`" width="90%" center>
      <p>请选择需要显示的参数（可多选）：</p>
      <el-checkbox-group v-model="selectedParams" style="margin-top: 10px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; max-height: 650px; overflow-y: auto;" class="scroll-wrapper">
        <el-checkbox 
          v-for="param in paramConfigsList" 
          :key="param.ParaID" 
          :label="param.ParaID"
          style="display: flex; align-items: center; margin-bottom: 0;"
        >
          <span style="margin-left: 8px; width: 340px; display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{param.ParaID }}-{{param.ParaName}}-{{ param.CNName}}</span>
        </el-checkbox>
      </el-checkbox-group>
      <template #footer>
        <el-button @click="cancelParamSelection">取消</el-button>
        <el-button type="primary" @click="confirmParamSelection">确认</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import {ref, onMounted, onUnmounted, computed, watch, nextTick} from "vue";
import { ElMessage, ElLoading, ElEmpty, ElDivider, ElTag, ElButton, ElSelect, ElOption, ElTooltip, ElIcon, ElDialog, ElCheckboxGroup, ElCheckbox, ElMessageBox } from "element-plus";
import TelemetryChart from "./charts/TelemetryChart.vue";
import RtspVideoPlayer from "./RtspVideoPlayer.vue";
import { Link, FullScreen, Refresh, ZoomOut } from "@element-plus/icons-vue";
import UnlinkIcon from "./icons/UnlinkIcon.vue";
import {taskTypeAPI} from "../api";
import {telemetryDataListAPI} from "../api";
import {useUdp} from "../api/modules/udpService";
import {getFormattedTaskList} from "../utils/fileUtils.js";

const currentTime = ref("");
const collectionStatus = ref("待机");
const collectionDuration = ref("00:00:00");
const collectionTimer = ref(null);
const collectionSeconds = ref(0);
const collectionId = ref(null); // 采集ID，用于停止采集
const showConfirmDialog = ref(false);
const telemetryChartRef = ref();
const taskList = ref([]);

// 用于显示paramConfigs的对话框
const showParamDialog = ref(false);
const currentTaskId = ref(null);
const currentTaskName = ref(null);
const selectedParams = ref([]);
const paramConfigsList = ref([]);

// 已确认的任务和参数选择
const confirmedSelection = ref(null);

// 窗口布局 - 与遥测图表共享
const windowLayout = ref(4); // 默认每行4路
const filterText = ref("");

// 视频列表 - 从视频流API获取
const videoList = ref([]);
const isLoadingVideoList = ref(false);

// WebSocket服务器配置
const wsServerUrl = ref("ws://localhost:8080");
const {
  isListening,
  startListening: startUdp,
  stopListening: stopUdp,
  onData
} = useUdp();
const multicastAddress = ref('');
const port = ref('');
const statusMessage = ref('');
const telemetryChartDataList = ref([]);
const selectIs = ref(true);
const telemetryDataSaveFileFolder=ref('');
const startListening = async () => {
  multicastAddress.value=localStorage.getItem('multicastAddress')
  port.value=localStorage.getItem('port')
  selectIs.value=false
  try {
    statusMessage.value = '正在启动 UDP 监听...';
    console.log('正在启动udp监听',multicastAddress.value,port.value);
    console.log('udp ip and port:',multicastAddress.value,port.value);
    console.log('全部参数：',paramConfigsList.value);
    console.log('选中的参数：',confirmedSelection.value);
    telemetryDataSaveFileFolder.value = generateCollectionTimestamp(1);
    await startUdp(multicastAddress.value, parseInt(port.value),currentTaskId.value,paramConfigsList.value,confirmedSelection.value.params,telemetryDataSaveFileFolder.value);
    statusMessage.value = `正在监听 ${multicastAddress.value}:${port.value}`;
  } catch (error) {
    statusMessage.value = `启动失败: ${error.message}`;
    console.error('Start listening error:', error);
    selectIs.value=true
  }
};

const stopListening = async () => {
  try {
    statusMessage.value = '正在停止 UDP 监听...';
    await stopUdp();
    statusMessage.value = '监听已停止';
    selectIs.value=true
  } catch (error) {
    statusMessage.value = `停止失败: ${error.message}`;
    console.error('Stop listening error:', error);
  }
};

// 监听udp组播数据接收
onData((data) => {
  try {
    console.log('udp接收到的数据为：', data);

    // 检查接收到的数据是否为数组（批量数据）
    if (Array.isArray(data) || (data && Array.isArray(data.data))) {
      // 批量处理多条数据
      const dataArray = Array.isArray(data) ? data : data.data;
      console.log('接收到批量数据，共', dataArray.length, '条');

      // 遍历处理每条数据
      dataArray.forEach((item, index) => {
        // 如果有结果且参数不为空，更新图表数据
          if (item && item.param && item.param.length > 0) {
            // 计算系统时间（毫秒）
            const sysTimeMs = item.sysTimeH * 3600000 + item.sysTimeM * 60000 + item.sysTimeS * 1000 + item.sysTimeMS;

            // 更新每个参数的图表数据
            item.param.forEach(param => {
              // 查找或创建该参数的历史数据
              let paramData = telemetryChartDataList.value.find(item => item.paramId === param.ParaID);

              if (!paramData) {
                // 创建新的参数数据对象
                paramData = {
                  paramId: param.ParaID,
                  paramName: param.CNName || param.ParaName || `参数${param.ParaID}`,
                  x: [], // 系统时间毫秒
                  y: []  // 参数值
                };
                telemetryChartDataList.value.push(paramData);
              }

              // 添加新数据点
              paramData.x.push(sysTimeMs);
              // 使用原始字节值的整数表示作为图表数据
              // 将十六进制字符串转换为整数
              let numericValue = param.value; // 默认使用解析后的值
              paramData.y.push(numericValue);

              // 限制数据点数量，保持图表性能
              const maxDataPoints = 100;
              if (paramData.x.length > maxDataPoints) {
                paramData.x.shift();
                paramData.y.shift();
              }
            });

            // 强制更新响应式数据
            telemetryChartDataList.value = [...telemetryChartDataList.value];
            console.log('遥测数据曲线图数据更新完成:', telemetryChartDataList.value);
          }
      });
    } else {
      // 处理单条数据（向后兼容）
      console.log('接收到单条数据');
      // 如果有数据且参数不为空，更新图表数据
      if (data && data.param && data.param.length > 0) {
        // 计算系统时间（毫秒）
        const sysTimeMs = data.sysTimeH * 3600000 + data.sysTimeM * 60000 + data.sysTimeS * 1000 + data.sysTimeMS;

          // 更新每个参数的图表数据
          data.param.forEach(param => {
            // 查找或创建该参数的历史数据
            let paramData = telemetryChartDataList.value.find(item => item.paramId === param.ParaID);

            if (!paramData) {
              // 创建新的参数数据对象
              paramData = {
                paramId: param.ParaID,
                paramName: param.CNName || param.ParaName || `参数${param.ParaID}`,
                x: [], // 系统时间毫秒
                y: []  // 参数值
              };
              telemetryChartDataList.value.push(paramData);
            }

            // 添加新数据点
            paramData.x.push(sysTimeMs);
            // 使用原始字节值的整数表示作为图表数据
            let numericValue = param.value; // 默认使用解析后的值
            paramData.y.push(numericValue);

            // 限制数据点数量，保持图表性能
            const maxDataPoints = 100;
            if (paramData.x.length > maxDataPoints) {
              paramData.x.shift();
              paramData.y.shift();
            }
          });

          // 强制更新响应式数据
          telemetryChartDataList.value = [...telemetryChartDataList.value];
          console.log('遥测数据曲线图数据更新完成:', telemetryChartDataList.value);
        }
    }

  } catch (error) {
    console.error('遥测数据保存失败:', error);
  }
});

// 加载任务文件
const loadTaskListData = async () => {
  try {
    // 从文件夹读取任务名称和ID
    const taskListData = await getFormattedTaskList();
    taskList.value = taskListData || [];
    selectIs.value = true;
    console.log('从文件夹加载任务列表成功:', taskList.value);
  } catch (error) {
    console.error('加载任务列表失败:', error);
    taskList.value = [];
    ElMessage.error('加载任务列表失败，请检查文件权限或文件格式');
  }
};

// 存储选中的ID
const selectedTaskIds = ref([]);

// 检查项是否被选中
const isItemSelected = (id) => {
  return selectedTaskIds.value.includes(id);
};

// 切换选择状态
const toggleSelection = (id, event) => {
  if (event) {
    const isRadio = event.target.tagName === 'INPUT' && event.target.type === 'radio';
    // 对于单选按钮，点击卡片不需要手动更新选中状态
    // 因为radio按钮组会自动处理互斥选择
    if (isRadio) {
      // 如果点击的是单选按钮，不执行下面的选择逻辑
      // 让单选按钮的原生行为来处理选中状态
      return;
    }
  }

  // 单选逻辑：直接设置选中的ID，替换掉之前的选择
  // 如果点击的是当前已选中的项，则取消选择
  if (isItemSelected(id)) {
    selectedTaskIds.value = [];
  } else {
    selectedTaskIds.value = [id];
    
    // 检查选中的任务是否有paramConfigs
    const selectedTask = taskList.value.find(task => task.id === id);
    if (selectedTask && selectedTask.paramConfigs && selectedTask.paramConfigs.length > 0) {
      // 保存当前任务ID
      currentTaskId.value = id;
      currentTaskName.value = selectedTask.name;
      // 设置paramConfigs列表
      console.log('选中的任务:', selectedTask);
      console.log('选中的任务的参数配置:', selectedTask.paramConfigs);
      paramConfigsList.value = selectedTask.paramConfigs;
      // 默认不选中任何参数
      selectedParams.value = [];
      // 显示参数选择对话框
      showParamDialog.value = true;
    }
  }
};

// 确认参数选择
const confirmParamSelection = () => {
  showParamDialog.value = false;
  // 保存选中的参数信息
  const selectedTask = taskList.value.find(task => task.id === currentTaskId.value);
  if (selectedTask && selectedParams.value.length > 0) {
    // 获取选中参数的名称（优先使用CNName，其次ParaName，最后ParaID）
    const selectedParamNames = paramConfigsList.value
      .filter(param => selectedParams.value.includes(param.ParaID))
      .map(param => {
        // 优先使用中文名称，其次英文名称，最后使用参数ID
        if (param.CNName && param.CNName.trim()) {
          return param.CNName;
        } else if (param.ParaName && param.ParaName.trim()) {
          return param.ParaName;
        } else {
          return `参数${param.ParaID}`;
        }
      });
    
    // 获取选中的完整参数对象
    const selectedFullParams = paramConfigsList.value
      .filter(param => selectedParams.value.includes(param.ParaID));
    
    // 保存已确认的选择
    confirmedSelection.value = {
      taskId: currentTaskId.value,
      taskName: currentTaskName.value,
      params: selectedFullParams, // 保存完整的参数对象
      paramNames: selectedParamNames
    };
    console.log('全部参数：',paramConfigsList.value);
    console.log('选中的参数：',confirmedSelection.value);
    console.log(`已确认的任务: ${currentTaskId.value}-${currentTaskName.value} 选中的参数:`, confirmedSelection.value);
  }
};

// 重新选择任务
const reselectTask = () => {
  // 清除已确认的选择
  confirmedSelection.value = null;
  // 清除当前选中的任务ID，允许用户重新选择
  selectedTaskIds.value = [];
  currentTaskId.value = null;
  currentTaskName.value = null;
  selectedParams.value = [];
  paramConfigsList.value = [];
};

// 取消参数选择
const cancelParamSelection = () => {
  showParamDialog.value = false;
};

// 加载视频流列表
const loadVideoStreamList = async () => {
  isLoadingVideoList.value = true;
  try {
    const { videoStreamAPI } = await import('../api/index.js');

    const response = await videoStreamAPI.getVideoStreams({
      pageNum: 1,
      pageSize: 1000,
      orderByColumn: 'streamSort',
      isAsc: 'asc'
    });

    if (response && response.code == 0) {
      const streams = response.rows || [];
      videoList.value = streams.map(stream => {
        let status = 'offline';
        let collecting = false;
        let isEnabled = true;

        if (stream.status === '0' || stream.status === 0) {
          isEnabled = true;
          collecting = true;
        } else if (stream.status === '1' || stream.status === 1) {
          isEnabled = false;
          collecting = false;
        } else {
          console.log(`未知状态值: ${stream.status}，默认为启用`);
          isEnabled = true;
          collecting = false;
        }

        return {
          id: stream.streamId,
          streamId: stream.streamId,
          src: stream.previewUrl || stream.captureUrl,
          streamUrl: stream.captureUrl || stream.previewUrl,
          status: status,
          isEnabled: isEnabled,
          collecting: collecting,
          name: stream.streamTitle,
          title: stream.streamTitle,
          type: 'network',
          lastCheck: null,
          errorMessage: "",
          remark: stream.remark,
          streamSort: stream.streamSort
        };
      });

      console.log('加载视频流列表成功:', videoList.value);
      ElMessage.success(`成功加载 ${videoList.value.length} 个视频流`);
    } else {
      throw new Error(response?.msg || '获取视频流列表失败');
    }
  } catch (error) {
    console.error('加载视频流列表失败:', error);
    ElMessage.error('加载视频流列表失败，请检查网络连接');
    videoList.value = [];
  } finally {
    isLoadingVideoList.value = false;
  }
};

const filteredVideoList = computed(() => {
  if (!filterText.value) return videoList.value;
  return videoList.value.filter((item) =>
      item.name.includes(filterText.value)
  );
});

// 视频网格样式计算
const gridStyle = computed(() => {
  return {
    display: "grid",
    gridTemplateColumns: `repeat(${windowLayout.value}, 1fr)`,
    gap: "16px",
    minHeight: 0,
    padding: "0",
  };
});

// 视频组件引用
const videoRefs = ref(new Map());

// 全屏状态跟踪
const fullscreenStates = ref(new Map());

let timer = null;

// 更新当前时间
const updateTime = () => {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, "0");
  const day = String(now.getDate()).padStart(2, "0");
  const hours = String(now.getHours()).padStart(2, "0");
  const minutes = String(now.getMinutes()).padStart(2, "0");
  const seconds = String(now.getSeconds()).padStart(2, "0");
  currentTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

// 格式化时间
const formatTime = (seconds) => {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = seconds % 60;
  return `${hours.toString().padStart(2, "0")}:${minutes
      .toString()
      .padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
};

// 开始采集计时
const startCollectionTimer = () => {
  collectionSeconds.value = 0;
  collectionTimer.value = setInterval(() => {
    collectionSeconds.value++;
    collectionDuration.value = formatTime(collectionSeconds.value);
  }, 1000);
};

// 停止采集计时
const stopCollectionTimer = () => {
  if (collectionTimer.value) {
    clearInterval(collectionTimer.value);
    collectionTimer.value = null;
  }
};

// 获取状态显示文本和样式
const getStatusDisplay = (video) => {
  if (!video.isEnabled) {
    return { text: "已停用", class: "disabled" };
  } else if (video.errorMessage) {
    return { text: "离线", class: "offline" };
  } else if (video.status === "online") {
    return { text: "在线", class: "online" };
  } else {
    return { text: "离线", class: "offline" };
  }
};

// 保存视频源配置到接口
const saveVideoSourceConfig = async (video) => {
  try {
    const { videoStreamAPI } = await import('../api/index.js');

    const result = await videoStreamAPI.updateVideoStream(video.streamId, {
      streamTitle: video.name,
      previewUrl: video.src,
      captureUrl: video.streamUrl,
      streamSort: video.streamSort || 1,
      status: video.collecting ? '0' : '1',
      remark: video.type
    });

    if (result && result.code == 0) {
      ElMessage.success(`${video.name} 配置已保存`);
    } else {
      ElMessage.warning(`${video.name} 配置保存失败`);
    }
  } catch (error) {
    console.error("保存配置失败:", error);
    ElMessage.warning(`${video.name} 配置保存失败，使用本地缓存`);

    const localConfig = JSON.parse(localStorage.getItem('videoSourcesConfig') || '{}');
    localConfig[video.streamId] = {
      name: video.name,
      streamUrl: video.streamUrl,
      enabled: video.collecting,
      type: video.type,
      lastUpdate: new Date().toISOString()
    };
    localStorage.setItem('videoSourcesConfig', JSON.stringify(localConfig));
  }
};

// 采集相关状态和方法
const collectionTimestamp = ref("");
const collectionProcesses = ref([]);
const isCollecting = ref(false);
const telemetryData = ref([]);

// 采集时间跟踪
const actualCollectionStartTime = ref(null);
const actualCollectionEndTime = ref(null);
const actualCollectionDuration = ref(0);

// 生成采集时间戳
const generateCollectionTimestamp = (formatType = 0) => {
  const now = new Date();
  const datePart = 
      now.getFullYear().toString() +
      (now.getMonth() + 1).toString().padStart(2, "0") +
      now.getDate().toString().padStart(2, "0");
  const timePart = 
      now.getHours().toString().padStart(2, "0") +
      now.getMinutes().toString().padStart(2, "0") +
      now.getSeconds().toString().padStart(2, "0");
  
  // formatType为1时返回不带下划线的格式，其他情况返回带下划线的格式
  return formatType === 1 ? datePart + timePart : datePart + "_" + timePart;
};

// 开始多路视频采集
const startVideoCollection = async () => {
  try {
    const collectingChannels = videoList.value.filter((v) => {
      return v.isEnabled && v.status === 'online';
    });

    console.log("=== 视频采集状态检查 ===");
    console.log("总视频数:", videoList.value.length);
    console.log("已启用的视频数:", videoList.value.filter(v => v.isEnabled).length);
    console.log("在线视频数:", videoList.value.filter(v => v.isEnabled && v.status === 'online').length);
    console.log("可采集的视频数:", collectingChannels.length);

    videoList.value.forEach((video, index) => {
      console.log(`视频${index + 1}: ${video.name} - 启用:${video.isEnabled} - 状态:${video.status}`);
    });

    console.log("开始采集", collectingChannels.length, "路视频");

    collectionDuration.value = "准备中...";
    collectionTimestamp.value = generateCollectionTimestamp();

    const streamIds = collectingChannels.map(video => video.id).join(',');

    console.log(`准备采集 ${collectingChannels.length} 路视频，streamIds: ${streamIds}`);

    const { videoSaveAPI } = await import('../api/index.js');

    const apiResult = await videoSaveAPI.startVideoSave({
      streamIds: streamIds,
      collectionTaskId: currentTaskId.value,
      collectionTaskName: currentTaskName.value
    });

    if (apiResult && apiResult.code === 0) {
      collectionId.value = apiResult.dataId || null;

      isCollecting.value = true;
      collectionStatus.value = "采集中";
      actualCollectionStartTime.value = new Date();

      startCollectionTimer();

      ElMessage.success(
          `开始采集 ${collectingChannels.length} 路视频，采集ID: ${collectionId.value}`
      );
    } else {
      console.error("采集启动失败:", apiResult?.msg || '未知错误');
      ElMessage.error(`采集启动失败: ${apiResult?.msg || '未知错误'}`);
      collectionDuration.value = "00:00:00";
      collectionTimestamp.value = "";
      collectionSeconds.value = 0;
      stopCollectionTimer();
    }
  } catch (error) {
    console.error("启动视频采集失败:", error);
    ElMessage.error(`启动视频采集失败: ${error.message}`);
    collectionDuration.value = "00:00:00";
    collectionTimestamp.value = "";
    collectionSeconds.value = 0;
    stopCollectionTimer();
  }
};

// 停止视频采集
const stopVideoCollection = async () => {
  try {
    actualCollectionDuration.value = collectionSeconds.value;
    actualCollectionEndTime.value = new Date();

    if (!collectionId.value) {
      console.warn("没有采集ID，无法停止采集");
      ElMessage.warning("没有采集ID，无法停止采集");
      return;
    }    
    const { videoSaveAPI } = await import('../api/index.js');
    const apiResult = await videoSaveAPI.stopVideoSave({
      dataId: collectionId.value
    });

    isCollecting.value = false;

    if (apiResult && apiResult.code === 0) {
      ElMessage.success(
          `视频采集已停止，实际采集时长: ${formatTime(
              actualCollectionDuration.value
          )}`
      );
      collectionId.value = null;
    } else {
      ElMessage.error(`停止采集失败: ${apiResult?.msg || '未知错误'}`);
    }
  } catch (error) {
    console.error("停止视频采集失败:", error);
    ElMessage.error("停止视频采集失败");
    isCollecting.value = false;
  }
};

// 采集前验证
const beforeCollectionValidate=()=>{
  let result = false;
  const collectingChannels = videoList.value.filter((v) => {
    return v.isEnabled && v.status === 'online';
  });

  if (collectingChannels.length === 0) {
    const enabledCount = videoList.value.filter(v => v.isEnabled).length;
    const onlineCount = videoList.value.filter(v => v.isEnabled && v.status === 'online').length;

    if (enabledCount === 0) {
      ElMessage.warning("没有启用的视频源，请联系管理员启用视频流");
    } else if (onlineCount === 0) {
      ElMessage.warning("没有在线的视频源，请检查视频流连接状态");
    } else {
      ElMessage.warning("没有可用的视频源，请检查视频源状态");
    }
  }else if (collectingChannels.length > 0){
    result = true;
  }
  if(result){
    const udpMulticastAddress =localStorage.getItem('multicastAddress')
    const udpPort=localStorage.getItem('port')
    if(!udpMulticastAddress&&!udpPort){
      result =false;
      ElMessage.warning('没有获取到udp组播地址和端口，请到系统设置去进行系统配置');
    }
    if(selectedTaskIds.value.length===0){
      result =false;
      ElMessage.warning('请先选择任务！');
    } else if (!confirmedSelection.value) {
      // 已选择任务但未确认参数
      result = false;
      ElMessage.warning('请选择并确认任务参数！');
    }
  }
  return result;
};

// 采集切换方法
const toggleCollection = async () => {
  if (collectionStatus.value === "采集中") {
    await stopCollection();
    await stopListening();
  } else {
    if(beforeCollectionValidate()){
      await startCollection();
      console.log('开始udp监听');      
      await startListening()
    }
  }
};

// 开始采集
const startCollection = async () => {
  await startVideoCollection();
};

// 停止采集
const stopCollection = async () => {
  showConfirmDialog.value = true;
  await stopListening()
  try {
    actualCollectionDuration.value = collectionSeconds.value;
    actualCollectionEndTime.value = new Date();

    console.log("停止采集调试信息:");
    console.log("collectionTimestamp.value:", collectionTimestamp.value);
    console.log("actualCollectionDuration.value:", actualCollectionDuration.value);
    console.log("collectionSeconds.value:", collectionSeconds.value);

    collectionStatus.value = "待机";

    if (collectionTimestamp.value && actualCollectionDuration.value > 0) {
      console.log("显示确认对话框");
      showConfirmDialog.value = true;
    } else {
      console.log("无采集数据，直接重置状态");
      ElMessage.warning("采集已停止，无采集数据");
      collectionTimestamp.value = "";
      actualCollectionStartTime.value = null;
      actualCollectionEndTime.value = null;
      actualCollectionDuration.value = 0;
      // 重置遥测图表数据
      telemetryChartDataList.value = [];
    }
    collectionDuration.value = "00:00:00";
    collectionSeconds.value = 0;
    stopCollectionTimer();
    console.log(collectionDuration.value);
  } catch (error) {
    console.error("停止采集失败:", error);
    ElMessage.error("停止采集失败");
    collectionDuration.value = "00:00:00";
    collectionSeconds.value = 0;
    stopCollectionTimer();
  }
};

// 视频卡片交互
const maximizeVideo = (i) => {
  const video = filteredVideoList.value[i];

  if (!video.isEnabled) {
    ElMessage.warning(`${video.name} 已停用，无法进行放大操作`);
    return;
  }

  if (video.status === 'offline') {
    ElMessage.warning(`${video.name} 当前离线，无法进行放大操作`);
    return;
  }

  const videoRef = videoRefs.value.get(video.id);
  if (videoRef && typeof videoRef.toggleFullscreen === 'function') {
    videoRef.toggleFullscreen();
  } else {
    console.warn('视频组件未找到或没有全屏方法');
  }
};

// 检查视频是否处于全屏状态
const isVideoFullscreen = (i) => {
  const video = filteredVideoList.value[i];

  if (fullscreenStates.value.has(video.id)) {
    const isFullscreen = fullscreenStates.value.get(video.id);
    return isFullscreen;
  }

  const videoRef = videoRefs.value.get(video.id);
  if (videoRef && typeof videoRef.isFullscreen !== 'undefined') {
    const isFullscreen = videoRef.isFullscreen;
    return isFullscreen;
  }

  return false;
};

// 获取全屏按钮的工具提示文本
const getFullscreenTooltip = (i) => {
  if (isVideoFullscreen(i)) {
    return '退出全屏';
  }
  return '最大化';
};

// 刷新网格布局
const refreshGrid = () => {
  console.log('布局已更改为每行', windowLayout.value, '路');
};

// 切换采集状态
const toggleCollect = async (i) => {
  if (collectionStatus.value === "采集中") {
    ElMessage.warning("采集进行中，无法修改采集状态");
    return;
  }

  const video = filteredVideoList.value[i];

  if (!video.isEnabled) {
    ElMessage.warning(`${video.name} 已停用，无法进行采集操作`);
    return;
  }

  if (video.status === 'offline') {
    ElMessage.warning(`${video.name} 当前离线，无法进行采集操作`);
    return;
  }

  video.collecting = !video.collecting;

  if (video.collecting) {
    video.collectStartTime = new Date();
    ElMessage.success(`${video.name} 已加入采集`);
  } else {
    video.collectStartTime = null;
    ElMessage.success(`${video.name} 已取消采集`);
  }

  await saveVideoSourceConfig(video);
};

// 确认保存
const confirmSave = async () => {
  console.log("=== 用户确认保存 ===");
  console.log("采集时间戳:", collectionTimestamp.value);
  console.log("实际采集时长:", actualCollectionDuration.value);

  showConfirmDialog.value = false;
  await stopListening()
  const params = {
    type:1,
    dataId:collectionId.value
  };
  console.log('更新遥测数据准备的数据参数:',params);
  await taskTypeAPI.updateTelemetryData(params);
  const saveOrCancelTelemetryParams = {
    type:1,
    dataId:collectionId.value,
    filePath:telemetryDataSaveFileFolder.value
  };
  const saveOrCancelTelemetryResult = await telemetryDataListAPI.saveOrCancelTelemetry(saveOrCancelTelemetryParams);
  console.log('保存遥测数据结果:', saveOrCancelTelemetryResult);
  if (!collectionTimestamp.value) {
    console.error("错误: 未找到采集时间戳");
    ElMessage.warning("未找到采集会话，无法保存文件");
    return;
  }

  try {
    const loadingInstance = ElLoading.service({
      lock: true,
      text: "正在停止采集...",
      background: "rgba(0, 0, 0, 0.7)",
    });

    if (isCollecting.value) {
      console.log("用户确认停止采集，请求停止接口...");
      await stopVideoCollection();
      await stopListening()
    }

    finalizeCollection(loadingInstance);

  } catch (error) {
    console.error("确认保存失败:", error);
    ElMessage.error("保存操作失败: " + error.message);
  }
};

// 取消保存
const cancelSave = async () => {
  console.log("=== 用户取消保存 ===");
  showConfirmDialog.value = false;
  const params = {
    type:0
  };
  await stopListening()
  await taskTypeAPI.updateTelemetryData(params);
  //用户取消保存后需要删除data表的数据和保存的视频文件
  const { videoSaveAPI } = await import('../api/index.js');
  const deleteResult = await videoSaveAPI.deleteData({
      dataId: collectionId.value,
      telemetryPath:telemetryDataSaveFileFolder.value
    });
  console.log('取消保存视频数据结果:', deleteResult);
  telemetryData.value = [];
  // 重置遥测图表数据
  telemetryChartDataList.value = [];
  console.log("遥测数据已清空");

  if (collectionTimestamp.value) {
    console.log("采集已取消，清理数据");
    ElMessage.info("已取消采集");
  }
  collectionTimestamp.value = "";
  actualCollectionStartTime.value = null;
  actualCollectionEndTime.value = null;
  actualCollectionDuration.value = 0;

  console.log("采集状态已重置，所有临时数据已清理");
};

// 处理视频播放器错误
const handleVideoError = (error) => {
  console.error(`视频播放器错误:`, error);

  const videoIndex = videoList.value.findIndex(video =>
      video.src === error.url || video.streamUrl === error.url
  );

  if (videoIndex !== -1 && videoList.value[videoIndex]) {
    const video = videoList.value[videoIndex];

    if (video.isEnabled) {
      video.status = 'offline';
      const friendlyError = error.detail && typeof error.detail === 'string' && !error.detail.includes('[object')
          ? error.detail
          : '视频流连接异常';
      video.errorMessage = friendlyError;
    }
  } else {
    console.warn('无法找到对应的视频索引，显示通用错误');
  }

  console.warn('视频播放错误，已记录错误信息');
};

// 处理视频重连失败
const handleVideoReconnectFailed = (data) => {
  console.error(`视频重连失败:`, data);
  console.log('handleVideoReconnectFailed函数被调用，接收到的数据:', data);

  console.log('查找视频索引，接收到的URL:', data.url);
  console.log('当前视频列表:', videoList.value.map(v => ({ id: v.id, src: v.src, streamUrl: v.streamUrl })));

  const videoIndex = videoList.value.findIndex(video =>
      video.src === data.url || video.streamUrl === data.url
  );

  console.log('找到的视频索引:', videoIndex);

  if (videoIndex !== -1 && videoList.value[videoIndex]) {
    const video = videoList.value[videoIndex];

    if (video.isEnabled) {
      video.status = 'offline';
      video.errorMessage = `网络连接异常，已尝试重连${data.attempts}次`;
      console.log(`视频 ${videoIndex} 重连失败${data.attempts}次，已设置为离线状态`);
    }
  } else {
    console.warn('无法找到对应的视频索引，显示通用错误');
  }

  console.warn('视频重连失败，已记录错误信息');
};

// 处理视频连接成功
const handleVideoConnected = (data) => {
  console.log(`视频连接成功:`, data);

  const videoIndex = videoList.value.findIndex(video =>
      video.src === data.url || video.streamUrl === data.url
  );

  if (videoIndex !== -1 && videoList.value[videoIndex]) {
    const video = videoList.value[videoIndex];

    if (video.isEnabled) {
      video.status = 'online';
      video.errorMessage = '';
      console.log(`视频 ${videoIndex} 连接成功，耗时: ${data.time}ms`);
    }
  } else {
    console.warn('无法找到对应的视频索引');
  }
};

// 处理全屏状态变化
const handleFullscreenChange = (isFullscreen, videoId) => {
  console.log(`视频 ${videoId} 全屏状态变化:`, isFullscreen);

  fullscreenStates.value.set(videoId, isFullscreen);

  import('vue').then(({ nextTick }) => {
    nextTick(() => {
      videoList.value = [...videoList.value];
      console.log('强制更新完成');
    });
  });
};

// 完成采集
const finalizeCollection = async (loadingInstance) => {
  try {
    console.log("=== 完成采集 ===");

    const collectingChannels = videoList.value.filter(
        (v) => v.isEnabled && v.status === 'online'
    );

    console.log("采集通道:", collectingChannels.map(c => ({ id: c.id, name: c.name })));

    if (collectingChannels.length === 0) {
      console.warn("警告: 没有找到采集通道");
      loadingInstance.close();
      ElMessage.warning("没有找到采集通道");
      return;
    }

    stopCollectionTimer();

    collectionDuration.value = "00:00:00";
    collectionSeconds.value = 0;

    // 先保存实际采集时长到临时变量
    const durationToShow = actualCollectionDuration.value;
    const channelCount = collectingChannels.length;
    // 获取选中任务的遥测数据参数数量
    const telemetryParamCount = paramConfigsList.value.length|| 0;
    
    // 重置所有采集相关状态
    collectionTimestamp.value = "";
    actualCollectionStartTime.value = null;
    actualCollectionEndTime.value = null;
    actualCollectionDuration.value = 0;
    // 重置遥测图表数据
    telemetryChartDataList.value = [];
    
    loadingInstance.close();

    ElMessage.success(
        `采集完成！采集时长: ${formatTime(actualCollectionDuration.value)}，采集了 ${channelCount} 路视频，采集了 ${telemetryParamCount} 个遥测数据参数`
    );

    console.log("✓ 采集完成");
    console.log("=== 保存流程完成 ===");
  } catch (error) {
    console.error("✗ 文件整理过程中发生错误:", error);
    loadingInstance.close();
    ElMessage.error("保存操作失败: " + error.message);
  }
};

// 添加浏览器beforeunload事件监听器
const handleBeforeUnload = (event) => {
  if (collectionStatus.value === '采集中') {
    event.preventDefault();
    event.returnValue = ''; // 对于旧版浏览器
    // 注意：现代浏览器会显示自己的确认消息，而不是我们自定义的消息
  }
};

// 监听采集状态变化，同步到全局变量
watch(collectionStatus, (newStatus) => {
  console.log('采集状态变更:', newStatus);
  // 同步到全局变量，供路由守卫使用
  if (typeof window !== 'undefined') {
    window.dataCollectionStatus = newStatus;
  }
}, { immediate: true });

onMounted(async () => {
  updateTime();
  timer = setInterval(updateTime, 1000);

  await loadTaskListData();
  await loadVideoStreamList();
  
  // 添加事件监听器
  window.addEventListener('beforeunload', handleBeforeUnload);
});

onUnmounted(() => {
  if (timer) clearInterval(timer);
  if (collectionTimer.value) clearInterval(collectionTimer.value);
  
  // 清理事件监听器
  window.removeEventListener('beforeunload', handleBeforeUnload);
  
  // 只在非采集中状态下自动停止监听
  // 如果正在采集，用户已经通过路由守卫处理了
  console.log('isListening.value',isListening.value);
  console.log('collectionStatus.value',collectionStatus.value);
  if (isListening.value && collectionStatus.value === '采集中') {
    stopCollection();
    cancelSave();
  }
});
</script>

<style scoped>
.data-collection {
  height: 100%;
  display: block;
  padding: 0 15px 15px 15px;
}
.status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: white;
  padding: 12px 20px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  flex-shrink: 0;
}
.status-bar .time{font-weight: bolder;}
.status-left {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
}
.status-right {
  display: flex;
  gap: 8px;
}
.video-toolbar {
  margin-top: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #fff;height: 50px;
}
.toolbar-left {
  display: flex;margin-left: 10px;
  align-items: center;
  gap: 8px;
}
.toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.toolbar-label {
  font-size: 14px;
  color: #333;
  margin-right: 4px;
}
.scroll-wrapper {
  height: calc((100% - 118px)/2);
  overflow: auto;
  background-color: #fff;box-shadow: 0 2px 8px rgb(0 0 0 / 6%);
  padding: 0 10px 10px 10px;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.loading-state p {
  margin-top: 16px;
  color: #666;
  font-size: 14px;
}
.video-grid {
  width: 100%;
  margin: 0 auto;
  min-height: 200px;
  display: grid;
  gap: 16px;
}

.video-card {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  min-height: 180px;
  aspect-ratio: 16/10;
  width: 100%;
  transition: all 0.2s ease;
}

.video-card.disabled {
  background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
  border: 2px solid #e5e7eb;
  box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);
  position: relative;
  opacity: 0.7;
}

.video-card.selected {
  border-color: #2563eb;
  background-color: #f0f9ff;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
  transition: all 0.2s ease;
}

.video-card-topbar {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}
.video-title {
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  background: rgba(0, 0, 0, 0.45);
  border-radius: 4px;
  padding: 2px 8px;
  pointer-events: auto;
}
.video-status-text {
  font-weight: bold;
  margin-left: 8px;
  font-size: 15px;
  letter-spacing: 1px;
}
.video-status-text.online {
  color: #21c521;
  text-shadow: 0 0 2px #0a7a0a;
}
.video-status-text.offline {
  color: #ff3b3b;
  text-shadow: 0 0 2px #a10000;
}
.video-status-text.connecting {
  color: #f59e0b;
  text-shadow: 0 0 2px #d97706;
  animation: pulse 1.5s ease-in-out infinite;
}

.video-status-text.disabled {
  color: #9ca3af;
  text-shadow: 0 0 2px #6b7280;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

.video-card-icons {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  display: flex;
  gap: 8px;
  pointer-events: auto;
}
.video-icon {
  color: #fff;
  font-size: 22px;
  cursor: pointer;
  transition: color 0.2s, transform 0.2s;
  opacity: 0.85;
}
.video-icon:hover {
  color: #ffd700;
  opacity: 1;
  transform: scale(1.18);
}
.video-icon.disabled {
  opacity: 0.3;
  cursor: not-allowed;
  pointer-events: none;
}

.video-icon.disabled:hover {
  color: #fff;
  opacity: 0.3;
  transform: none;
}

.video-icon.fullscreen {
  color: #ffd700 !important;
  opacity: 1;
  transform: scale(1.1);
}

.video-icon.fullscreen:hover {
  color: #ffed4e !important;
  transform: scale(1.2);
}

.video-card-body {
  flex: 1 1 0;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  height: 100%;
}
.video-placeholder {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #666;
  font-size: 16px;
  text-align: center;
  padding: 20px;
  height: 100%;
}

.video-placeholder.disabled {
  padding: 15px 10px;
}

.disabled-content {
  max-width: 200px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.disabled-title {
  color: #6b7280;
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 8px 0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.disabled-message {
  color: #9ca3af;
  font-size: 12px;
  margin: 0 0 12px 0;
  line-height: 1.3;
  background: rgba(156, 163, 175, 0.1);
  padding: 6px 8px;
  border-radius: 4px;
  border-left: 2px solid #9ca3af;
  text-align: center;
  max-height: 3em;
  overflow: hidden;
  text-overflow: ellipsis;
}

.video-player {
  width: 100% !important;
  height: 100% !important;
}
.video-container,
.video-container video {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
}
.chart-section {
  background: white;
  margin-top: 10px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  height: calc((100% - 118px)/2);
  flex-shrink: 0;
}
@media (max-width: 1200px) {
  .video-grid {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}
@media (max-width: 768px) {
  .data-collection {
    padding: 12px;
    gap: 12px;
  }
  .video-grid {
    grid-template-columns: 1fr !important;
  }
  .status-left {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
}
.data-container {
  width: 100%;
  height: calc((100% - 118px)/2);
  margin: 10px auto 0 auto;
  background-color: #fff;
  box-shadow: 0 2px 8px rgb(0 0 0 / 6%);overflow: hidden;
}

.data-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #e5e7eb;
}

.section-title {
  margin: 0;
  font-size: 20px;
  color: #1e293b;
}

.control-buttons {
  display: flex;
  align-items: center;
  gap: 16px;
}

.select-all-checkbox {
  display: flex;
  align-items: center;
  cursor: pointer;
}

.select-all-checkbox input {
  display: none;
}

.checkbox-icon {
  width: 18px;
  height: 18px;
  border: 2px solid #64748b;
  border-radius: 4px;
  display: inline-block;
  position: relative;
  margin-right: 6px;
  transition: all 0.2s ease;
}

.select-all-checkbox input:checked + .checkbox-icon::after {
  content: '✓';
  position: absolute;
  color: #2563eb;
  font-size: 14px;
  top: -2px;
  left: 2px;
}

.select-all-checkbox input:checked + .checkbox-icon {
  border-color: #2563eb;
}

.checkbox-text {
  color: #334155;
  font-size: 14px;
}

.clear-selection {
  background-color: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 4px;
  padding: 6px 12px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #334155;
}

.clear-selection:hover {
  background-color: #e2e8f0;
}

.clear-selection:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background-color: #f8fafc;
}

.selection-info {
  color: #64748b;
  font-size: 14px;
}

/* 网格布局 - 一行5个 */
.data-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 20px;
  margin-bottom: 30px;
}

.data-card {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 16px;
  background-color: #ffffff;
  transition: all 0.2s ease;
  cursor: pointer;
  position: relative;
}
.task-content{
  height: calc(100% - 45px);
  overflow-y: auto;padding: 10px;
}
.task-content .data-card{
  padding:0;font-size:16px;
}

.data-card:hover {
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  border-color: #cbd5e1;
}

.data-card.selected {
  border-color: #2563eb;
  background-color: #f0f9ff;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

.card-checkbox {
  position: absolute;
  top: 16px;
  right: 16px;
}

.card-checkbox input {
  display: none;
}

.custom-checkbox {
  width: 18px;
  height: 18px;
  border: 2px solid #64748b;
  border-radius: 4px;
  display: inline-block;
  position: relative;
  transition: all 0.2s ease;
}

.card-checkbox input:checked + .custom-checkbox::after {
  content: '✓';
  position: absolute;
  color: #2563eb;
  font-size: 14px;
  top: -2px;
  left: 2px;
}

.card-checkbox input:checked + .custom-checkbox {
  border-color: #2563eb;
}

.card-content {
  margin-right: 24px; /* 为右侧复选框留出空间 */
  padding: 10px;
}

.data-name {
  font-size: 16px;
  color: #1e293b;
}

/* 数据面板样式 */
.data-panel {
  margin-top: 20px;
  padding: 16px;
  background-color: #f8fafc;
  border-radius: 8px;
}

.data-panel h4 {
  margin: 0 0 16px 0;
  font-size: 16px;
  color: #1e293b;
}

.loading {
  text-align: center;
  padding: 20px;
  color: #64748b;
  font-style: italic;
}

.data-list {
  max-height: 300px;
  overflow-y: auto;
}

.data-item {
  background-color: #ffffff;
  border-radius: 4px;
  padding: 12px;
  margin-bottom: 10px;
  border-left: 3px solid #2563eb;
}

.data-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 12px;
  color: #64748b;
}

.message {
  font-family: monospace;
  font-size: 13px;
  color: #1e293b;
  white-space: pre-wrap;
}

/* 当前选择任务信息样式 */
.selected-task-info {
  background-color: #f0f9ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 20px;
  box-shadow: 0 2px 8px rgba(37, 99, 235, 0.1);
}

.info-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.info-header h3 {
  margin: 0;
  font-size: 18px;
  color: #1e40af;
}

.info-content {
  background-color: #ffffff;
  border-radius: 6px;
  padding: 12px;
}

.info-content p,
.info-content div {
  margin: 8px 0;
  font-size: 14px;
  color: #334155;
  line-height: 1.5;
  display: flex;
  align-items: center;
}

/* 标签样式优化 */
.info-content .el-tag {
  background-color: #eff6ff;
  border-color: #bfdbfe;
  color: #1d4ed8;
  transition: all 0.2s ease;
}

.info-content .el-tag:hover {
  background-color: #dbeafe;
  border-color: #93c5fd;
}

.info-content strong {
  color: #1e293b;
}

/* 响应式调整 */
@media (max-width: 1024px) {
  .data-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 768px) {
  .data-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .data-grid {
    grid-template-columns: 1fr;
  }

  .data-controls {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .control-buttons {
    width: 100%;
    justify-content: space-between;
  }
}
</style>
